home *** CD-ROM | disk | FTP | other *** search
- /* $Author: ecsv38 $ $Date: 90/08/21 14:45:59 $ $Revision: 1.1 $ */
- /* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */
-
- #include "Counter.h"
-
- #include "Sim.h"
- #include "SimEventList.h"
-
-
- static Counter timer;
- static SimEventList eventlist;
-
- Event *cause()
- {
- if ( debug_level(1) ) {
- cout << "\n---Begin{eventlist}\n";
- ::eventlist.print();
- cout << "\n---End{eventlist}\n";
- }
-
-
- Event *ev = ::eventlist.get();
- if ( ev == 0 ) return 0;
-
- if ( ev->eventTime() > ::timer() )
- ::timer.set(ev->eventTime());
-
- return ev;
- }
-
- short cancel(const int eid)
- {
- Event *ev = ::eventlist.remove(eid);
-
- if ( ev == 0 ) return 0;
- else {
- delete ev;
- return 1;
- }
- }
-
- double simtime()
- {
- return timer();
- }
-
- Entity::Entity(char *const s)
- {
- static int eid = 0;
-
- entity_name = s, entity_id = eid++;
- }
-
- void
- Entity::schedule(const double delay, Event *const ev)
- {
- if ( delay < 0 ) {
- cout << form("%s: invalid delay %g\n", entity_name, delay);
- exit(-1);
- }
- ev->scheduled_by(this);
- ev->eventTime(::timer() + delay);
-
- ::eventlist.append(ev);
- }
-
- short
- Resource::reserve(Entity *bywho, const int event_type)
- {
- resource_used = 1;
-
- if ( bywho == 0 )
- cout << form("** Error: reserve by null entity\n");
-
- bywho->currentEvent(event_type);
- bywho->afterTime = 0;
-
- if ( available > 0 ) {
- --available;
- servedQ.append(bywho);
- return 1;
- }
- else {
- blockedQ.append(bywho);
- return 0;
- }
- }
-
- short
- Resource::preempt(Entity *bywho, const int event_type)
- {
- resource_used = 1;
-
- if ( bywho == 0 )
- cout << form("** Error: preempt by null entity\n");
-
- bywho->currentEvent(event_type);
- bywho->afterTime = 0;
-
- if ( available > 0 ) {
- --available;
- servedQ.append(bywho);
- return 1;
- }
- else {
- Entity *minPrioEnt = servedQ.remove(servedQ.min_entity_id());
- if ( minPrioEnt->priority() >= bywho->priority() ) { // no preempt
- blockedQ.append(bywho);
- servedQ.append(minPrioEnt);
- return 0;
- }
- else { // preempt
- servedQ.append(bywho);
- Event *stopped = ::eventlist.remove(minPrioEnt);
- if ( stopped == 0 ) {
- cout << form("** Error: no events for preempted entity\n");
- return 0;
- }
- minPrioEnt->afterTime = stopped->eventTime() - simtime();
- minPrioEnt->currentEvent(stopped->type());
- blockedQ.insert(minPrioEnt);
- delete stopped;
- return 1;
- }
- }
- }
-
- void
- Resource::release(Entity *const bywho)
- {
- Entity *entity;
-
- if ( bywho == 0 )
- cout << form("** Error: release by null entity\n");
-
- if ( debug_level(1) ) {
- cout << form("Releasing resource %s\n", resource_name);
- cout << "\n---Begin{blockedQ}\n";
- blockedQ.print();
- cout << "\n---End{blockedQ}\n";
- }
-
- if ( servedQ.remove(bywho->id()) == 0 )
- cout << form("** Error: release without reserve\n");
-
- if ( ( entity = blockedQ.get() ) != 0 ) {
- Event *event = new Event(entity->currentEvent());
- entity->schedule(entity->afterTime, event);
- if ( entity->afterTime == 0 ) ++available;
- }
- else ++available;
- }
-
- void
- Resource::set(const int sz)
- {
- if ( resource_used ) {
- cout << form("%s: resource already used. cannot set size\n",
- resource_name);
- exit(-1);
- }
- available = sz;
- }
-
-